package com.lhy.mymall.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lhy.mymall.exception.ExceptionEnum;
import com.lhy.mymall.exception.MallException;
import com.lhy.mymall.mapper.CategoryMapper;
import com.lhy.mymall.pojo.Category;
import com.lhy.mymall.request.AddCategoryReq;
import com.lhy.mymall.service.CategoryService;
import com.lhy.mymall.vo.CategoryVO;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: 卢辉宇
 * @date: 2022/12/14 13:27
 * @description:
 */
@Service
public class CategoryServiceImp implements CategoryService {

    @Resource
    CategoryMapper categoryMapper;

    /**
     * 添加目录业务方法
     * @param addCategoryReq 需要添加的字段（提前封装好了的）
     */
    @Override
    public void addCategory(AddCategoryReq addCategoryReq) throws MallException {
        //创建一个实体类对象，用于等一下保存进数据库
        Category category = new Category();
        //把传进来的字段赋值给刚创建的实体类对象
        //传统方法（一个一个的set）
//        category.setName(addCategoryReq.getName());
//        category.setType(addCategoryReq.getType());
//        ...
        //使用spring工具直接把addCategoryReq对象的对属性复制给category的对应属性（前提属性名命名一致）
        BeanUtils.copyProperties(addCategoryReq,category);

        //调用mapper层查询数据库是否已经存在相同目录。。。
        Category categoryOld = categoryMapper.selectByName(category.getName());
        if (categoryOld!=null){
            throw new MallException(ExceptionEnum.NAME_EXISTED);
        }

        //开始插入数据库...
        int count = categoryMapper.insert(category);
        if(count==0||count>1){
            throw new MallException(ExceptionEnum.INSERT_FAILED);
        }
    }

    @Override
    public void deleteCategory(Integer id) throws MallException {
        //通过mapper层查找数据库。。。
        Category categoryOld = categoryMapper.selectById(id);
        //库中没有，删除失败
        if (categoryOld==null){
            throw new MallException(ExceptionEnum.DELETE_FAILED);
        }

        //执行删除操作
        int count = categoryMapper.deleteById(id);
        //删除失败
        if (count==0||count>1){
            throw new MallException(ExceptionEnum.DELETE_FAILED);
        }
    }

    /**
     *分页业务方法
     * @param pageNum
     * @param pageSize
     * @return 用PageHelper封装后的目录列表
     */
    @Override
    public PageInfo listForAdmin(Integer pageNum, Integer pageSize){

        //1.先要调用PageHelper.startPage(pageNum, pageSize,排序字段)进行分页配置
        PageHelper.startPage(pageNum, pageSize,"type,order_num");

        //2.再把目录全部查询出来放到list里
        List<Category> selectList = categoryMapper.selectList();


        //把查到的全部目录列表封装成PageInfo
        PageInfo pageInfo = new PageInfo(selectList);
        return pageInfo;
    }

    /**
     *
     * @return 目录列表集合，包含了递归查询到的父子层级关系的集合
     */
    @Override
    @Cacheable(value = "listCategoryForCustomer")
    public List<CategoryVO> listCategoryForCustomer(){
        //创建一个集合对象用于存放查到的目录列表
        List<CategoryVO> categoryVOList = new ArrayList<>();

        //通过父id递归查找全部目录列表。。。
        //第一次查询时先找到顶级目录
        recursivelyFindCategories(categoryVOList,0);
        return categoryVOList;
    }

    public void recursivelyFindCategories(List<CategoryVO> categoryVOList,Integer parentId){
        //在mapper层中查找以parentId为父目录的所有记录。。。
        List<Category> categoryList = categoryMapper.selectListByParentId(parentId);

        /**
         * 把得到的父目录的所有记录分别开始递归获取子目录
         */
        //如果得到的categoryList不为空，则继续递归
        if(!CollectionUtils.isEmpty(categoryList)){
            //把categoryList结合转变成categoryVOList集合
            for (int i = 0; i < categoryList.size(); i++) {
                Category category =  categoryList.get(i);
                //创建categoryVO用于存放得到的目录对象
                CategoryVO categoryVO = new CategoryVO();
                //通过spring工具把从数据库查到的category目录copy到categoryVO
                BeanUtils.copyProperties(category,categoryVO);
                //把categoryVO对象放进categoryVOList集合里
                categoryVOList.add(categoryVO);

                //开始递归存放到子目录中,并开始查找以自己的id为父id的所有记录
                recursivelyFindCategories(categoryVO.getChileCategory(),categoryVO.getId());
            }
        }

    }


}
